import 'package:flutter/material.dart';

/// Dart关键词示例
class KeywordsExample extends StatefulWidget {
  const KeywordsExample({super.key});

  @override
  State<KeywordsExample> createState() => _KeywordsExampleState();
}

class _KeywordsExampleState extends State<KeywordsExample> {
  String result = '点击下方按钮查看关键词示例';

  void _demonstrateVarDynamicObject() {
    // var - 类型推断
    var name = 'Alice'; // 推断为String
    var age = 25; // 推断为int

    // dynamic - 动态类型
    dynamic anything = 'String';
    anything = 42; // 可以改变类型
    anything = ['list']; // 可以是任何类型

    // Object - 所有类型的基类
    Object obj = 'Hello';
    // obj.length; // ✗ 错误：Object没有length属性

    setState(() {
      result =
          '''
【var vs dynamic vs Object】

1. var - 类型推断:
var name = 'Alice'; // 推断为String类型
name = 'Bob';       // ✓ 可以
name = 123;         // ✗ 错误：类型已确定

特点:
• 编译时确定类型
• 类型一旦确定不能改变
• 有类型安全检查
• IDE有代码提示

2. dynamic - 动态类型:
dynamic anything = 'String';
anything = 42;      // ✓ 可以
anything = ['list']; // ✓ 可以

特点:
• 类型可以改变
• 绕过编译时类型检查
• 运行时才检查类型
• 失去IDE提示
• 容易出错

3. Object - 所有类型的基类:
Object obj = 'Hello';
obj = 123;          // ✓ 可以（都是Object）
obj.length;         // ✗ 错误：需要类型转换

特点:
• 所有类型的父类
• 可以接收任何值
• 需要类型转换才能使用具体方法
• 保留类型检查

对比:
┌─────────┬──────────┬──────────┐
│ var     │ dynamic  │ Object   │
├─────────┼──────────┼──────────┤
│ 类型推断│ 动态类型 │ 顶层类型 │
│ 类型固定│ 类型可变 │ 类型可变 │
│ 类型安全│ 无类型检查│ 部分检查│
│ IDE提示 │ 无提示   │ 无提示   │
└─────────┴──────────┴──────────┘

推荐使用:
• 优先使用 var 或显式类型
• 避免使用 dynamic（除非必要）
• Object 用于泛型约束

实际值:
name: $name (${name.runtimeType})
anything: $anything (${anything.runtimeType})
obj: $obj (${obj.runtimeType})
      ''';
    });
  }

  void _demonstrateVoid() {
    void noReturnValue() {
      // 不返回任何值
      print('执行操作');
    }

    void alsoNoReturn() {
      return; // 可以有空的return
    }

    setState(() {
      result = '''
【void 关键字】
void表示函数不返回值。

void printMessage(String msg) {
  print(msg);
  // 没有return语句
}

void doSomething() {
  print('doing...');
  return; // 可以有空return提前退出
}

特点:
• 明确表示无返回值
• 不能将void赋值给变量
• 可以有空的return语句

示例:
void greet() {
  print('Hello');
}

var result = greet(); // ✗ 错误：void不是值

Flutter中的应用:
• 回调函数常用void
• VoidCallback类型

Widget build(BuildContext context) {
  return ElevatedButton(
    onPressed: () {
      // VoidCallback，返回void
      print('Pressed');
    },
    child: Text('Button'),
  );
}

typedef VoidCallback = void Function();

void vs 不写返回类型:
void function1() { }  // ✓ 明确无返回值
function2() { }       // 推断返回dynamic

最佳实践:
• 无返回值时明确写void
• 提高代码可读性
• 帮助IDE和编译器
      ''';
    });
  }

  void _demonstrateNull() {
    setState(() {
      result = '''
【null 关键字】
null表示"没有值"。

int? age = null;
String? name = null;

// 检查null
if (name == null) {
  print('name是null');
}

if (name != null) {
  print('name不是null');
}

null的特点:
• 是一个特殊的值
• 只能赋给可空类型
• null是NullType的唯一实例

String name = null;    // ✗ 错误：非空类型
String? name = null;   // ✓ 可以：可空类型

处理null的方式:
1. 空值检查:
if (value != null) {
  use(value);
}

2. 空值合并:
String name = nullableName ?? 'Guest';

3. 条件访问:
int? length = text?.length;

4. 断言非空（谨慎使用）:
String name = nullableName!;

null在集合中:
List<String?> items = ['a', null, 'b'];
// 可空元素列表

List<String>? items = null;
// 可空的列表

Map<String, String?> map = {
  'key1': 'value',
  'key2': null,
};

默认值:
class User {
  String? name;     // 默认为null
  int? age;         // 默认为null
  String city = 'Beijing'; // 默认值
}

注意:
• null不是0
• null不是空字符串''
• null不是false
• null就是"没有值"

检查集合为空:
List<String>? list;
if (list == null || list.isEmpty) {
  print('列表为空或null');
}

// 更简洁
if (list?.isEmpty ?? true) {
  print('列表为空或null');
}
      ''';
    });
  }

  void _demonstrateThisSuper() {
    setState(() {
      result = '''
【this 和 super 关键字】

1. this - 引用当前实例:

class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
  // 等价于:
  // Person(String name, int age) {
  //   this.name = name;
  //   this.age = age;
  // }
  
  void introduce() {
    print('I am \${this.name}'); // this可以省略
    print('I am \$name');         // 效果相同
  }
  
  // 命名构造函数调用另一个构造函数
  Person.guest() : this('Guest', 0);
}

使用场景:
• 构造函数参数简写
• 消除命名歧义
• 链式构造函数调用

2. super - 引用父类:

class Animal {
  String name;
  Animal(this.name);
  
  void makeSound() {
    print('\$name makes a sound');
  }
}

class Dog extends Animal {
  String breed;
  
  // 调用父类构造函数
  Dog(String name, this.breed) : super(name);
  // 或简写为:
  // Dog(super.name, this.breed);
  
  @override
  void makeSound() {
    super.makeSound(); // 调用父类方法
    print('\$name barks!');
  }
}

使用场景:
• 调用父类构造函数
• 调用父类方法
• 访问父类属性

示例:
class Button extends StatelessWidget {
  const Button({super.key}); // 传递key给父类
  
  @override
  Widget build(BuildContext context) {
    return super.build(context); // 很少需要
  }
}

this vs super:
┌────────┬──────────────┐
│ this   │ 当前类实例   │
│ super  │ 父类         │
└────────┴──────────────┘

注意:
• 构造函数中必须先调用super
• 不能在static方法中使用this
• super只能访问父类，不能跨级
      ''';
    });
  }

  void _demonstrateIsAs() {
    Object obj = 'Hello';

    // is - 类型检查
    bool isString = obj is String;
    bool isNotString = obj is! int;

    // as - 类型转换
    if (obj is String) {
      String str = obj; // 自动类型提升
      // String str = obj as String; // 或显式转换
    }

    setState(() {
      result =
          '''
【is 和 as 关键字】

1. is - 类型检查:
Object obj = 'Hello';

if (obj is String) {
  print('obj是String类型');
  // 这里obj自动提升为String类型
  print(obj.length); // 可以直接使用
}

if (obj is! int) {
  print('obj不是int类型');
}

obj is String:  $isString
obj is! int:    $isNotString

2. as - 类型转换:
Object obj = 'Hello';
String str = obj as String; // 强制转换

⚠️ 注意：如果类型不匹配会抛出异常
Object num = 42;
String bad = num as String; // 💥 运行时错误！

安全的转换模式:
if (obj is String) {
  // 这里不需要as，已经自动提升
  String str = obj;
  print(str.length);
}

实际应用:
// 处理动态类型
dynamic data = fetchData();

if (data is Map<String, dynamic>) {
  String name = data['name'];
} else if (data is List) {
  int count = data.length;
}

// Widget类型转换
Widget widget = getWidget();
if (widget is Text) {
  String text = widget.data ?? '';
}

// 安全转换（返回null而不是抛出异常）
String? str = obj is String ? obj as String : null;
// 或使用tryCast模式函数（需要自己实现）

is vs as:
┌──────┬────────────────┐
│ is   │ 检查类型       │
│      │ 返回bool       │
│      │ 自动类型提升   │
├──────┼────────────────┤
│ as   │ 强制类型转换   │
│      │ 类型不匹配报错 │
│      │ 显式转换       │
└──────┴────────────────┘

最佳实践:
• 优先使用 is 检查
• 利用类型提升避免 as
• 只在确定类型时使用 as
• 考虑使用 is + 类型提升替代 as

✓ 推荐:
if (obj is String) {
  print(obj.length);
}

✗ 避免:
print((obj as String).length);
      ''';
    });
  }

  void _demonstrateKeywordsSummary() {
    setState(() {
      result = '''
【Dart关键词总结】

类型相关:
┌─────────┬────────────────────┐
│ var     │ 类型推断           │
│ dynamic │ 动态类型           │
│ Object  │ 顶层类型           │
│ void    │ 无返回值           │
│ null    │ 空值               │
└─────────┴────────────────────┘

修饰符:
┌─────────┬────────────────────┐
│ final   │ 运行时常量         │
│ const   │ 编译时常量         │
│ static  │ 类成员             │
│ late    │ 延迟初始化         │
└─────────┴────────────────────┘

类和对象:
┌─────────┬────────────────────┐
│ class   │ 定义类             │
│ extends │ 继承               │
│ with    │ 混入Mixin          │
│ this    │ 当前实例           │
│ super   │ 父类               │
│ new     │ 创建对象（可省略） │
└─────────┴────────────────────┘

访问控制:
┌─────────┬────────────────────┐
│ _       │ 私有（前缀下划线） │
│ public  │ 公开（默认）       │
└─────────┴────────────────────┘

类型检查和转换:
┌─────────┬────────────────────┐
│ is      │ 类型检查           │
│ is!     │ 类型检查取反       │
│ as      │ 类型转换           │
└─────────┴────────────────────┘

异步:
┌─────────┬────────────────────┐
│ async   │ 异步函数           │
│ await   │ 等待Future         │
│ yield   │ 生成Stream值       │
│ async*  │ 异步生成器         │
│ sync*   │ 同步生成器         │
└─────────┴────────────────────┘

控制流:
┌─────────┬────────────────────┐
│ if      │ 条件判断           │
│ else    │ 否则分支           │
│ for     │ 循环               │
│ while   │ 循环               │
│ do      │ do-while循环       │
│ switch  │ 多分支选择         │
│ case    │ 分支情况           │
│ break   │ 跳出循环           │
│ continue│ 继续下次循环       │
│ return  │ 返回值             │
└─────────┴────────────────────┘

异常处理:
┌─────────┬────────────────────┐
│ try     │ 尝试执行           │
│ catch   │ 捕获异常           │
│ finally │ 最终执行           │
│ throw   │ 抛出异常           │
│ rethrow │ 重新抛出           │
└─────────┴────────────────────┘

其他重要关键词:
┌─────────┬────────────────────┐
│ import  │ 导入库             │
│ export  │ 导出库             │
│ part    │ 库分割             │
│ library │ 库声明             │
│ show    │ 选择性导入         │
│ hide    │ 排除导入           │
│ as      │ 导入别名（也用于类型转换）│
│ required│ 必需参数           │
│ abstract│ 抽象类             │
│ interface│接口              │
│ mixin   │ 混入定义           │
└─────────┴────────────────────┘

记忆技巧:
1. 类型： var dynamic Object void null
2. 常量： final const late
3. 面向对象： class extends with this super
4. 异步： async await Future Stream
5. 类型操作： is as
      ''';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Dart 关键词'), backgroundColor: Theme.of(context).colorScheme.inversePrimary),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // 说明卡片
            Card(
              color: Colors.deepPurple.shade50,
              child: const Padding(
                padding: EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('🔑 关键词概述', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                    SizedBox(height: 8),
                    Text(
                      'Dart的核心关键词：\n'
                      '• var/dynamic/Object：类型声明\n'
                      '• void：无返回值\n'
                      '• null：空值\n'
                      '• this/super：对象引用\n'
                      '• is/as：类型操作',
                      style: TextStyle(fontSize: 14),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // 代码示例区域
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(color: Colors.grey.shade200, borderRadius: BorderRadius.circular(8)),
              child: const Text('''// 类型关键词
var name = 'Alice';
dynamic anything = 42;
Object obj = 'Hello';
void function() { }
String? nullable = null;

// 对象关键词
class MyClass {
  MyClass(this.value);
  final int value;
}

// 类型操作
if (obj is String) {
  String str = obj as String;
}''', style: TextStyle(fontFamily: 'monospace', fontSize: 13)),
            ),
            const SizedBox(height: 16),

            // 交互按钮
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(
                  onPressed: _demonstrateVarDynamicObject,
                  icon: const Icon(Icons.text_fields),
                  label: const Text('var/dynamic/Object'),
                ),
                ElevatedButton.icon(onPressed: _demonstrateVoid, icon: const Icon(Icons.block), label: const Text('void')),
                ElevatedButton.icon(onPressed: _demonstrateNull, icon: const Icon(Icons.do_not_disturb), label: const Text('null')),
                ElevatedButton.icon(
                  onPressed: _demonstrateThisSuper,
                  icon: const Icon(Icons.account_tree),
                  label: const Text('this/super'),
                ),
                ElevatedButton.icon(onPressed: _demonstrateIsAs, icon: const Icon(Icons.transform), label: const Text('is/as')),
                ElevatedButton.icon(onPressed: _demonstrateKeywordsSummary, icon: const Icon(Icons.list_alt), label: const Text('关键词总结')),
              ],
            ),
            const SizedBox(height: 16),

            // 结果展示区域
            Card(
              elevation: 4,
              child: Container(
                width: double.infinity,
                padding: const EdgeInsets.all(16),
                constraints: const BoxConstraints(minHeight: 150),
                child: Text(result, style: const TextStyle(fontSize: 14, fontFamily: 'monospace')),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
